home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
datatypes
/
hsn_dt
/
source
/
dispatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
6KB
|
236 lines
/******************************************************************************
*
* HSN Datatype, based on the sourcecode found in OS3.1 Native Developer Kit
*
* Written by Christian Buchner
*
******************************************************************************
* dispatch.c
*/
#include "classbase.h"
/*****************************************************************************/
#define DEBUG 1
#if DEBUG
#define DB(x) x
#include <stdarg.h>
void __stdargs Error(struct ClassBase *cb,UBYTE *Msg,...)
{
va_list Arg;
struct EasyStruct Req={sizeof(struct EasyStruct),0,"HSN debug message",0,"Okay"};
va_start(Arg,Msg);
Req.es_TextFormat=Msg;
EasyRequestArgs(NULL,&Req,0,Arg);
va_end(Arg);
}
#else
#define DB(x)
#endif
/*****************************************************************************/
Class *initClass (struct ClassBase * cb)
{
Class *cl;
if (cl = MakeClass (HSNDTCLASS, SOUNDDTCLASS, NULL, NULL, 0L))
{
cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
cl->cl_UserData = (ULONG) cb;
AddClass (cl);
}
return (cl);
}
/*****************************************************************************/
ULONG ASM Dispatch (REG (a0) Class * cl, REG (a2) Object * o, REG (a1) Msg msg)
{
struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
ULONG retval = 0L;
switch (msg->MethodID)
{
case OM_NEW:
if (retval = DoSuperMethodA (cl, o, msg))
{
if (!(ConvertObjectData (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList)))
{
CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
retval = NULL;
}
}
break;
/* Let the superclass handle everything else */
default:
retval = (ULONG) DoSuperMethodA (cl, o, msg);
break;
}
return (retval);
}
/*****************************************************************************/
struct HSNHeader
{
UBYTE HSN_ID[8]; /* $00 */
UBYTE Unknown[12]; /* $08 */
ULONG Size; /* $14 */
UWORD Pitch; /* $18 */
UBYTE Unknown2[22]; /* $1a */
/* $30 */
};
/*****************************************************************************/
BOOL ConvertObjectData (struct ClassBase * cb, Class * cl, Object * o, struct TagItem * attrs)
{
LONG ErrorCode=0;
struct FileInfoBlock *fib;
struct VoiceHeader *vhdr;
STRPTR Title;
BPTR FH;
struct HSNHeader *HSNHeader;
UBYTE HSNDesc[42]="";
ULONG Memory;
UBYTE *Sample;
ULONG Size;
Title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
getdtattrs (cb, o,
SDTA_VoiceHeader, &vhdr,
DTA_Handle, &FH,
TAG_DONE);
if (FH && vhdr)
{
/* Allocate a temporary file info block */
if (!(fib = (struct FileInfoBlock *) AllocMem (sizeof (struct FileInfoBlock), NULL)))
{
ErrorCode=ERROR_NO_FREE_STORE;
}
else
{
/* Get the size of the file */
if (ExamineFH (FH, fib))
{
Size = fib->fib_Size;
}
else
{
Seek (FH, 0, OFFSET_END);
Size = Seek (FH, 0, OFFSET_BEGINNING);
}
/* Free the temporary file info block */
FreeMem (fib, sizeof (struct FileInfoBlock));
/* Allocate header structure */
if (!(HSNHeader=AllocVec(sizeof(struct HSNHeader),MEMF_ANY)))
{
ErrorCode=ERROR_NO_FREE_STORE;
}
else
{
/* Calculate size from actual file length */
/* So even crippled or overlong files can be played completely */
Size-=sizeof(struct HSNHeader);
/* Read in sample header */
if (Read(FH,HSNHeader,sizeof(struct HSNHeader))==sizeof(struct HSNHeader))
{
/* Versions 1.0 and 1.1 are supported */
if (strcmp("HSND1.1",HSNHeader->HSN_ID) && strcmp("HSND1.0",HSNHeader->HSN_ID))
{
ErrorCode=ERROR_OBJECT_WRONG_TYPE;
}
else
{
/* Version 1.1 features a short description */
if (HSNHeader->HSN_ID[6]=='1')
{
Size-=sizeof(HSNDesc);
Read(FH,HSNDesc,sizeof(HSNDesc));
}
/* sound.datatype V40 can replay */
/* directly from Fast RAM */
Memory = (SuperClassBase->lib_Version>39) ?
MEMF_ANY : MEMF_CHIP;
/* Allocate a buffer with the calculated size */
if (!(Sample=AllocVec(Size,Memory)))
{
ErrorCode=ERROR_NO_FREE_STORE;
}
else
{
/* This implies that sample data is 8 bit signed */
/* Just read the sample into the buffer */
if (Read(FH,Sample,Size)==Size)
{
/* Fill in the VoiceHeader */
memset(vhdr,0,sizeof(struct VoiceHeader));
vhdr->vh_OneShotHiSamples = Size;
vhdr->vh_SamplesPerSec = 10*HSNHeader->Pitch;
vhdr->vh_Octaves = 1;
vhdr->vh_Compression = CMP_NONE;
vhdr->vh_Volume = 64;
/* Tell the super-class about the attributes */
setdtattrs (cb, o,
DTA_ObjName, Title,
SDTA_Sample, Sample,
SDTA_SampleLength, Size,
SDTA_Period, (ULONG)(SysBase->ex_EClockFrequency*5)/(ULONG)vhdr->vh_SamplesPerSec,
SDTA_Volume, 64,
SDTA_Cycles, 1,
TAG_DONE);
}
}
}
}
FreeVec(HSNHeader);
}
}
}
if (ErrorCode)
{
SetIoErr(ErrorCode);
return(FALSE);
}
return(TRUE);
}
/*****************************************************************************/
ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
{
return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
}
/*****************************************************************************/
ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
{
return (GetDTAttrsA (o, (struct TagItem *) & data));
}